#ifndef APIS_HPP
#define APIS_HPP
#include "pch.hpp"
#include "sts.hpp"

template <typename T>
std::optional<T>
get_config(T (*get)(GKeyFile *, char const *, char const *, GError **),
           GKeyFile *config, char const *group, char const *key);
//  {
//     GError *error = nullptr;
//     std::optional<T> value = get(config, group, key, &error);
//     if (error) {
//         g_error_free(error);
//         return {};
//     }
//     return value;
// }

char *get_user_shell_with_fallback();
void load_config(GtkWindow *window, VteTerminal *vte, GtkWidget *scrollbar,
                 GtkWidget *hbox, ConfigInfo *info, char **icon,
                 bool *show_scrollbar);
void set_config(GtkWindow *window, VteTerminal *vte, GtkWidget *scrollbar,
                GtkWidget *hbox, ConfigInfo *info, char **icon,
                bool *show_scrollbar_ptr, GKeyFile *config);

void adjust_font_size(VteTerminal *vte, GdkWindow *window, int font_size);

void set_size_hints(GtkWindow *window, VteTerminal *vte);

void load_theme(GtkWindow *window, VteTerminal *vte, GKeyFile *config,
                HintInfo &hints);
void get_vte_padding(VteTerminal *vte, int *left, int *top, int *right,
                     int *bottom);
std::optional<GdkRGBA> get_config_color(GKeyFile *config, char const *section,
                                        char const *key);
void override_background_color(GtkWidget *widget, GdkRGBA *rgba);
std::optional<cairo_pattern_t *>
get_config_cairo_color(GKeyFile *config, char const *group, char const *key);

void drag_data_received_cb(GtkWidget *, GdkDragContext *, int, int,
                           GtkSelectionData *data, unsigned, unsigned,
                           VteTerminal *vte);
void exit_with_status(VteTerminal *, int status);
void exit_with_success(VteTerminal *);
gboolean entry_key_press_cb(GtkEntry *entry, GdkEventKey *event,
                            KeybindInfo *info);
gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, KeybindInfo *info);
gboolean position_overlay_cb(GtkBin *overlay, GtkWidget *widget,
                             GdkRectangle *alloc);
gboolean button_press_cb(VteTerminal *vte, GdkEventButton *event,
                         ConfigInfo const *info);
void bell_cb(GtkWidget *vte, gboolean *urgent_on_bell);
gboolean draw_cb(DrawCallbackInfo const *info, cairo_t *cr);
gboolean focus_cb(GtkWindow *window);
void on_alpha_screen_changed(GtkWindow *window, GdkScreen *, void *);
gboolean window_state_cb(GtkWindow *, GdkEventWindowState *event,
                         KeybindInfo *info);
void window_title_cb(VteTerminal *vte, gboolean *dynamic_title);
void spawn_callback(VteTerminal *terminal, GPid pid, GError *error,
                    gpointer user_data);
void launch_url(char *browser, char const *text, SearchPanelInfo *info);
void synthesize_keypress(GtkWidget *widget, unsigned keyval);
void exit_command_mode(VteTerminal *vte, SelectInfo *select);
void toggle_visual(VteTerminal *vte, SelectInfo *select, Vi_Mode mode);
void move_backward_blank_word(VteTerminal *vte, SelectInfo *select);
void move_forward_blank_word(VteTerminal *vte, SelectInfo *select);
void move(VteTerminal *vte, SelectInfo *select, long col, long row);
void search(VteTerminal *vte, char const *pattern, bool reverse);
void move_backward_word(VteTerminal *vte, SelectInfo *select);
void move_forward_word(VteTerminal *vte, SelectInfo *select);
void move_forward_end_word(VteTerminal *vte, SelectInfo *select);
void move_forward_end_blank_word(VteTerminal *vte, SelectInfo *select);
void set_cursor_column(VteTerminal *vte, SelectInfo const *select, long column);
template <typename F>
void move_first(VteTerminal *vte, SelectInfo *select, F is_match);
std::unique_ptr<char, decltype(&g_free)>
get_text_range(VteTerminal *vte, long start_row, long start_col, long end_row,
               long end_col);
void move_to_eol(VteTerminal *vte, SelectInfo *select);
gboolean draw_cb(DrawCallbackInfo const *info, cairo_t *cr);
long get_count(SelectInfo *select);
void draw_marker(cairo_t *cr, PangoFontDescription const *desc,
                 HintInfo const *hints, long x, long y, char const *msg,
                 bool active);
void launch_browser(char *browser, char *url);
void update_selection(VteTerminal *vte, SelectInfo const *select);
long first_row(VteTerminal *vte);
void move_to_row_start(VteTerminal *vte, SelectInfo *select, long row);
long last_row(VteTerminal *vte);
long top_row(VteTerminal *vte);
long middle_row(VteTerminal *vte);
long bottom_row(VteTerminal *vte);
void copy_selection(VteTerminal *vte);
void overlay_show(SearchPanelInfo *info, Overlay_Mode mode, VteTerminal *vte);
void open_selection(char *browser, VteTerminal *vte);
void find_urls(VteTerminal *vte, SearchPanelInfo *panel_info);
void increase_font_scale(VteTerminal *vte);
void decrease_font_scale(VteTerminal *vte);
void reset_font_scale(VteTerminal *vte, gdouble scale);
void increase_font_scale(VteTerminal *vte);
void decrease_font_scale(VteTerminal *vte);
void launch_in_directory(VteTerminal *vte);
void enter_command_mode(VteTerminal *vte, SelectInfo *select);
void find_urls(VteTerminal *vte, SearchPanelInfo *panel_info);
void overlay_show(SearchPanelInfo *info, Overlay_Mode mode, VteTerminal *vte);
void copy_selection(VteTerminal *vte);
gboolean modify_key_feed(GdkEventKey *event, KeybindInfo *info,
                         std::map<int, char const *> const &table);

char *check_match(VteTerminal *vte, GdkEventButton *event);
template <typename F>
void move_backward(VteTerminal *vte, SelectInfo *select, F is_word);
template <typename F>
void move_forward(VteTerminal *vte, SelectInfo *select, F is_word,
                  bool goto_word_end);
void update_scroll(VteTerminal *vte);
bool is_word_char(gunichar c);
void draw_rectangle(cairo_t *cr, double x, double y, double height,
                    double width, double radius);
GtkTreeModel *create_completion_model(VteTerminal *vte);
#endif // header file protect
